from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError
from typing import Optional

from app.core.security import decode_access_token
from app.modules.users.models import UserModel
from app.modules.users.services import UserService
from app.core.exceptions import AuthException

# auto_error=False 表示当 token 不存在时，FastAPI 不会自动抛出异常，而是将 token 设为 None
# 这样我们就可以在 get_current_user 中自定义错误信息
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/users/login", auto_error=False)


async def get_current_user(token: Optional[str] = Depends(oauth2_scheme)) -> UserModel:
    """
    一个 FastAPI 依赖项，用于：
    1. 从请求头中提取 JWT。
    2. 验证并解码 JWT。
    3. 从数据库中获取当前用户。
    4. 如果有任何错误，则抛出统一的认证异常。
    
    :param token: FastAPI 会自动从请求头中注入 token。
    :return: 当前用户对应的 UserModel 对象。
    """
    credentials_exception = AuthException(
        message="用户未登录或登录已过期，请重新登录",
        # 可以在 data 中添加详细的错误头信息
        data=None,
    )
    
    if token is None:
        raise credentials_exception

    payload = decode_access_token(token)
    if payload is None:
        raise credentials_exception
    
    username: Optional[str] = payload.get("sub")
    if username is None:
        raise credentials_exception
    
    user = await UserService.get_by_username(username)
    if user is None:
        raise credentials_exception
        
    return user 